﻿// Decompiled with JetBrains decompiler
// Type: UnityEngine.Profiling.Profiler
// Assembly: UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
// MVID: E6AE6B5A-2752-4B07-9528-C8B77C62CE79
// Assembly location: C:\Users\windys\Unity\2021.3.39f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.CoreModule.dll
// XML documentation location: C:\Users\windys\Unity\2021.3.39f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.CoreModule.xml

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using Unity.Collections;
using Unity.Collections.LowLevel.Unsafe;
using Unity.Profiling;
using UnityEngine.Bindings;
using UnityEngine.Scripting;
using UnityEngine.Scripting.APIUpdating;

#nullable disable
namespace UnityEngine.Profiling
{
  /// <summary>
  ///   <para>Controls the from script.</para>
  /// </summary>
  [NativeHeader("Runtime/Utilities/MemoryUtilities.h")]
  [UsedByNativeCode]
  [NativeHeader("Runtime/Allocator/MemoryManager.h")]
  [NativeHeader("Runtime/ScriptingBackend/ScriptingApi.h")]
  [NativeHeader("Runtime/Profiler/Profiler.h")]
  [MovedFrom("UnityEngine")]
  [NativeHeader("Runtime/Profiler/ScriptBindings/Profiler.bindings.h")]
  public sealed class Profiler
  {
    internal const uint invalidProfilerArea = 4294967295;

    private Profiler()
    {
    }

    public static extern bool supported { [NativeMethod(Name = "profiler_is_available", IsFreeFunction = true), MethodImpl(MethodImplOptions.InternalCall)] get; }

    /// <summary>
    ///   <para>Specifies the file to use when writing profiling data.</para>
    /// </summary>
    [StaticAccessor("ProfilerBindings", StaticAccessorType.DoubleColon)]
    public static extern string logFile { [MethodImpl(MethodImplOptions.InternalCall)] get; [MethodImpl(MethodImplOptions.InternalCall)] set; }

    /// <summary>
    ///   <para>Enables the logging of profiling data to a file.</para>
    /// </summary>
    public static extern bool enableBinaryLog { [NativeMethod(Name = "ProfilerBindings::IsBinaryLogEnabled", IsFreeFunction = true), MethodImpl(MethodImplOptions.InternalCall)] get; [NativeMethod(Name = "ProfilerBindings::SetBinaryLogEnabled", IsFreeFunction = true), MethodImpl(MethodImplOptions.InternalCall)] set; }

    /// <summary>
    ///   <para>Sets the maximum amount of memory that Profiler uses for buffering data. This property is expressed in bytes.</para>
    /// </summary>
    public static extern int maxUsedMemory { [NativeMethod(Name = "ProfilerBindings::GetMaxUsedMemory", IsFreeFunction = true), MethodImpl(MethodImplOptions.InternalCall)] get; [NativeMethod(Name = "ProfilerBindings::SetMaxUsedMemory", IsFreeFunction = true), MethodImpl(MethodImplOptions.InternalCall)] set; }

    /// <summary>
    ///   <para>Enables the Profiler.</para>
    /// </summary>
    public static extern bool enabled { [NativeMethod(Name = "profiler_is_enabled", IsFreeFunction = true, IsThreadSafe = true), NativeConditional("ENABLE_PROFILER"), MethodImpl(MethodImplOptions.InternalCall)] get; [NativeMethod(Name = "ProfilerBindings::SetProfilerEnabled", IsFreeFunction = true), MethodImpl(MethodImplOptions.InternalCall)] set; }

    /// <summary>
    ///   <para>Enables the recording of callstacks for managed allocations.</para>
    /// </summary>
    public static extern bool enableAllocationCallstacks { [NativeMethod(Name = "ProfilerBindings::IsAllocationCallstackCaptureEnabled", IsFreeFunction = true), MethodImpl(MethodImplOptions.InternalCall)] get; [NativeMethod(Name = "ProfilerBindings::SetAllocationCallstackCaptureEnabled", IsFreeFunction = true), MethodImpl(MethodImplOptions.InternalCall)] set; }

    /// <summary>
    ///   <para>Enable or disable a given ProfilerArea.</para>
    /// </summary>
    /// <param name="area">The area you want to enable or disable.</param>
    /// <param name="enabled">Enable or disable the collection of data for this area.</param>
    [FreeFunction("ProfilerBindings::profiler_set_area_enabled")]
    [Conditional("ENABLE_PROFILER")]
    [MethodImpl(MethodImplOptions.InternalCall)]
    public static extern void SetAreaEnabled(ProfilerArea area, bool enabled);

    /// <summary>
    ///   <para>The number of ProfilerArea|Profiler Areas that you can profile.</para>
    /// </summary>
    public static int areaCount => Enum.GetNames(typeof (ProfilerArea)).Length;

    /// <summary>
    ///   <para>Returns whether or not a given ProfilerArea is currently enabled.</para>
    /// </summary>
    /// <param name="area">Which area you want to check the state of.</param>
    /// <returns>
    ///   <para>Returns whether or not a given ProfilerArea is currently enabled.</para>
    /// </returns>
    [FreeFunction("ProfilerBindings::profiler_is_area_enabled")]
    [NativeConditional("ENABLE_PROFILER")]
    [MethodImpl(MethodImplOptions.InternalCall)]
    public static extern bool GetAreaEnabled(ProfilerArea area);

    /// <summary>
    ///   <para>Displays the recorded profile data in the profiler.</para>
    /// </summary>
    /// <param name="file">The name of the file containing the frame data, including extension.</param>
    [Conditional("UNITY_EDITOR")]
    public static void AddFramesFromFile(string file)
    {
      if (string.IsNullOrEmpty(file))
        UnityEngine.Debug.LogError((object) "AddFramesFromFile: Invalid or empty path");
      else
        Profiler.AddFramesFromFile_Internal(file, true);
    }

    [StaticAccessor("profiling::GetProfilerSessionPtr()", StaticAccessorType.Arrow)]
    [NativeMethod(Name = "LoadFromFile")]
    [NativeConditional("ENABLE_PROFILER && UNITY_EDITOR")]
    [NativeHeader("Modules/ProfilerEditor/Public/ProfilerSession.h")]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private static extern void AddFramesFromFile_Internal(string file, bool keepExistingFrames);

    /// <summary>
    ///   <para>Enables profiling on the thread from which you call this method.</para>
    /// </summary>
    /// <param name="threadGroupName">The name of the thread group to which the thread belongs.</param>
    /// <param name="threadName">The name of the thread.</param>
    [Conditional("ENABLE_PROFILER")]
    public static void BeginThreadProfiling(string threadGroupName, string threadName)
    {
      if (string.IsNullOrEmpty(threadGroupName))
        throw new ArgumentException("Argument should be a valid string", nameof (threadGroupName));
      if (string.IsNullOrEmpty(threadName))
        throw new ArgumentException("Argument should be a valid string", nameof (threadName));
      Profiler.BeginThreadProfilingInternal(threadGroupName, threadName);
    }

    [NativeMethod(Name = "ProfilerBindings::BeginThreadProfiling", IsFreeFunction = true, IsThreadSafe = true)]
    [NativeConditional("ENABLE_PROFILER")]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private static extern void BeginThreadProfilingInternal(
      string threadGroupName,
      string threadName);

    /// <summary>
    ///   <para>Frees the internal resources used by the Profiler for the thread.</para>
    /// </summary>
    [NativeConditional("ENABLE_PROFILER")]
    public static void EndThreadProfiling()
    {
    }

    /// <summary>
    ///   <para>Begin profiling a piece of code with a custom label.</para>
    /// </summary>
    /// <param name="name">A string to identify the sample in the Profiler window.</param>
    /// <param name="targetObject">An object that provides context to the sample,.</param>
    [Conditional("ENABLE_PROFILER")]
    [MethodImpl((MethodImplOptions) 256)]
    public static void BeginSample(string name)
    {
      Profiler.ValidateArguments(name);
      Profiler.BeginSampleImpl(name, (UnityEngine.Object) null);
    }

    /// <summary>
    ///   <para>Begin profiling a piece of code with a custom label.</para>
    /// </summary>
    /// <param name="name">A string to identify the sample in the Profiler window.</param>
    /// <param name="targetObject">An object that provides context to the sample,.</param>
    [Conditional("ENABLE_PROFILER")]
    [MethodImpl((MethodImplOptions) 256)]
    public static void BeginSample(string name, UnityEngine.Object targetObject)
    {
      Profiler.ValidateArguments(name);
      Profiler.BeginSampleImpl(name, targetObject);
    }

    [MethodImpl((MethodImplOptions) 256)]
    private static void ValidateArguments(string name)
    {
      if (string.IsNullOrEmpty(name))
        throw new ArgumentException("Argument should be a valid string.", nameof (name));
    }

    [NativeMethod(Name = "ProfilerBindings::BeginSample", IsFreeFunction = true, IsThreadSafe = true)]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private static extern void BeginSampleImpl(string name, UnityEngine.Object targetObject);

    /// <summary>
    ///   <para>Ends the current profiling sample.</para>
    /// </summary>
    [Conditional("ENABLE_PROFILER")]
    [NativeMethod(Name = "ProfilerBindings::EndSample", IsFreeFunction = true, IsThreadSafe = true)]
    [MethodImpl(MethodImplOptions.InternalCall)]
    public static extern void EndSample();

    /// <summary>
    ///   <para>Resize the profiler sample buffers to allow the desired amount of samples per thread.</para>
    /// </summary>
    [Obsolete("maxNumberOfSamplesPerFrame has been depricated. Use maxUsedMemory instead")]
    public static int maxNumberOfSamplesPerFrame
    {
      get => 0;
      set
      {
      }
    }

    /// <summary>
    ///   <para>Heap size used by the program.</para>
    /// </summary>
    /// <returns>
    ///   <para>Size of the used heap in bytes, (or 0 if the profiler is disabled).</para>
    /// </returns>
    [Obsolete("usedHeapSize has been deprecated since it is limited to 4GB. Please use usedHeapSizeLong instead.")]
    public static uint usedHeapSize => (uint) Profiler.usedHeapSizeLong;

    /// <summary>
    ///   <para>Returns the number of bytes that Unity has allocated. This does not include bytes allocated by external libraries or drivers.</para>
    /// </summary>
    /// <returns>
    ///   <para>Size of the memory allocated by Unity (or 0 if the profiler is disabled).</para>
    /// </returns>
    public static extern long usedHeapSizeLong { [NativeMethod(Name = "GetUsedHeapSize", IsFreeFunction = true), MethodImpl(MethodImplOptions.InternalCall)] get; }

    /// <summary>
    ///   <para>Returns the runtime memory usage of the resource.</para>
    /// </summary>
    /// <param name="o"></param>
    [Obsolete("GetRuntimeMemorySize has been deprecated since it is limited to 2GB. Please use GetRuntimeMemorySizeLong() instead.")]
    public static int GetRuntimeMemorySize(UnityEngine.Object o)
    {
      return (int) Profiler.GetRuntimeMemorySizeLong(o);
    }

    /// <summary>
    ///   <para>Gathers the native-memory used by a Unity object.</para>
    /// </summary>
    /// <param name="o">The target Unity object.</param>
    /// <returns>
    ///   <para>The amount of native-memory used by a Unity object. This returns 0 if the Profiler is not available.</para>
    /// </returns>
    [NativeMethod(Name = "ProfilerBindings::GetRuntimeMemorySizeLong", IsFreeFunction = true)]
    [MethodImpl(MethodImplOptions.InternalCall)]
    public static extern long GetRuntimeMemorySizeLong([NotNull("ArgumentNullException")] UnityEngine.Object o);

    /// <summary>
    ///   <para>Returns the size of the mono heap.</para>
    /// </summary>
    [Obsolete("GetMonoHeapSize has been deprecated since it is limited to 4GB. Please use GetMonoHeapSizeLong() instead.")]
    public static uint GetMonoHeapSize() => (uint) Profiler.GetMonoHeapSizeLong();

    /// <summary>
    ///   <para>Returns the size of the reserved space for managed-memory.</para>
    /// </summary>
    /// <returns>
    ///   <para>The size of the managed heap.</para>
    /// </returns>
    [NativeMethod(Name = "scripting_gc_get_heap_size", IsFreeFunction = true)]
    [MethodImpl(MethodImplOptions.InternalCall)]
    public static extern long GetMonoHeapSizeLong();

    /// <summary>
    ///   <para>Returns the used size from mono.</para>
    /// </summary>
    [Obsolete("GetMonoUsedSize has been deprecated since it is limited to 4GB. Please use GetMonoUsedSizeLong() instead.")]
    public static uint GetMonoUsedSize() => (uint) Profiler.GetMonoUsedSizeLong();

    /// <summary>
    ///   <para>Gets the allocated managed memory for live objects and non-collected objects.</para>
    /// </summary>
    /// <returns>
    ///   <para>Returns a long integer value of the memory in use.</para>
    /// </returns>
    [NativeMethod(Name = "scripting_gc_get_used_size", IsFreeFunction = true)]
    [MethodImpl(MethodImplOptions.InternalCall)]
    public static extern long GetMonoUsedSizeLong();

    /// <summary>
    ///   <para>Sets the size of the temp allocator.</para>
    /// </summary>
    /// <param name="size">Size in bytes.</param>
    /// <returns>
    ///   <para>Returns true if requested size was successfully set. Will return false if value is disallowed (too small).</para>
    /// </returns>
    [StaticAccessor("GetMemoryManager()", StaticAccessorType.Dot)]
    [NativeConditional("ENABLE_MEMORY_MANAGER")]
    [MethodImpl(MethodImplOptions.InternalCall)]
    public static extern bool SetTempAllocatorRequestedSize(uint size);

    /// <summary>
    ///   <para>Returns the size of the temp allocator.</para>
    /// </summary>
    /// <returns>
    ///   <para>Size in bytes.</para>
    /// </returns>
    [NativeConditional("ENABLE_MEMORY_MANAGER")]
    [StaticAccessor("GetMemoryManager()", StaticAccessorType.Dot)]
    [MethodImpl(MethodImplOptions.InternalCall)]
    public static extern uint GetTempAllocatorSize();

    /// <summary>
    ///   <para>Returns the amount of allocated and used system memory.</para>
    /// </summary>
    [Obsolete("GetTotalAllocatedMemory has been deprecated since it is limited to 4GB. Please use GetTotalAllocatedMemoryLong() instead.")]
    public static uint GetTotalAllocatedMemory() => (uint) Profiler.GetTotalAllocatedMemoryLong();

    /// <summary>
    ///   <para>The total memory allocated by the internal allocators in Unity. Unity reserves large pools of memory from the system; this includes double the required memory for textures becuase Unity keeps a copy of each texture on both the CPU and GPU. This function returns the amount of used memory in those pools.</para>
    /// </summary>
    /// <returns>
    ///   <para>The amount of memory allocated by Unity. This returns 0 if the Profiler is not available.</para>
    /// </returns>
    [NativeConditional("ENABLE_MEMORY_MANAGER")]
    [StaticAccessor("GetMemoryManager()", StaticAccessorType.Dot)]
    [NativeMethod(Name = "GetTotalAllocatedMemory")]
    [MethodImpl(MethodImplOptions.InternalCall)]
    public static extern long GetTotalAllocatedMemoryLong();

    /// <summary>
    ///   <para>Returns the amount of reserved but not used system memory.</para>
    /// </summary>
    [Obsolete("GetTotalUnusedReservedMemory has been deprecated since it is limited to 4GB. Please use GetTotalUnusedReservedMemoryLong() instead.")]
    public static uint GetTotalUnusedReservedMemory()
    {
      return (uint) Profiler.GetTotalUnusedReservedMemoryLong();
    }

    /// <summary>
    ///   <para>Unity allocates memory in pools for usage when unity needs to allocate memory. This function returns the amount of unused memory in these pools.</para>
    /// </summary>
    /// <returns>
    ///   <para>The amount of unused memory in the reserved pools. This returns 0 if the Profiler is not available.</para>
    /// </returns>
    [StaticAccessor("GetMemoryManager()", StaticAccessorType.Dot)]
    [NativeMethod(Name = "GetTotalUnusedReservedMemory")]
    [NativeConditional("ENABLE_MEMORY_MANAGER")]
    [MethodImpl(MethodImplOptions.InternalCall)]
    public static extern long GetTotalUnusedReservedMemoryLong();

    /// <summary>
    ///   <para>Returns the amount of reserved system memory.</para>
    /// </summary>
    [Obsolete("GetTotalReservedMemory has been deprecated since it is limited to 4GB. Please use GetTotalReservedMemoryLong() instead.")]
    public static uint GetTotalReservedMemory() => (uint) Profiler.GetTotalReservedMemoryLong();

    /// <summary>
    ///   <para>The total memory Unity has reserved.</para>
    /// </summary>
    /// <returns>
    ///   <para>Memory reserved by Unity in bytes. This returns 0 if the Profiler is not available.</para>
    /// </returns>
    [NativeConditional("ENABLE_MEMORY_MANAGER")]
    [StaticAccessor("GetMemoryManager()", StaticAccessorType.Dot)]
    [NativeMethod(Name = "GetTotalReservedMemory")]
    [MethodImpl(MethodImplOptions.InternalCall)]
    public static extern long GetTotalReservedMemoryLong();

    [NativeConditional("ENABLE_MEMORY_MANAGER")]
    public static unsafe long GetTotalFragmentationInfo(NativeArray<int> stats)
    {
      return Profiler.InternalGetTotalFragmentationInfo((IntPtr) stats.GetUnsafePtr<int>(), stats.Length);
    }

    [StaticAccessor("GetMemoryManager()", StaticAccessorType.Dot)]
    [NativeMethod(Name = "GetTotalFragmentationInfo")]
    [NativeConditional("ENABLE_MEMORY_MANAGER")]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private static extern long InternalGetTotalFragmentationInfo(IntPtr pStats, int count);

    /// <summary>
    ///         <para>Returns the amount of allocated memory for the graphics driver, in bytes.
    /// 
    /// Only available in development players and editor.</para>
    ///       </summary>
    [StaticAccessor("GetMemoryManager()", StaticAccessorType.Dot)]
    [NativeMethod(Name = "GetRegisteredGFXDriverMemory")]
    [NativeConditional("ENABLE_PROFILER")]
    [MethodImpl(MethodImplOptions.InternalCall)]
    public static extern long GetAllocatedMemoryForGraphicsDriver();

    /// <summary>
    ///   <para>Write metadata associated with the current frame to the Profiler stream.</para>
    /// </summary>
    /// <param name="id">Module identifier. Used to distinguish metadata streams between different plugins, packages or modules.</param>
    /// <param name="tag">Data stream index.</param>
    /// <param name="data">Binary data.</param>
    [Conditional("ENABLE_PROFILER")]
    public static unsafe void EmitFrameMetaData(Guid id, int tag, Array data)
    {
      System.Type type = data != null ? data.GetType().GetElementType() : throw new ArgumentNullException(nameof (data));
      if (!UnsafeUtility.IsBlittable(type))
        throw new ArgumentException(string.Format("{0} type must be blittable", (object) type));
      Profiler.Internal_EmitGlobalMetaData_Array((void*) &id, 16, tag, data, data.Length, UnsafeUtility.SizeOf(type), true);
    }

    [Conditional("ENABLE_PROFILER")]
    public static unsafe void EmitFrameMetaData<T>(Guid id, int tag, List<T> data) where T : struct
    {
      if (data == null)
        throw new ArgumentNullException(nameof (data));
      System.Type type = typeof (T);
      if (!UnsafeUtility.IsBlittable(typeof (T)))
        throw new ArgumentException(string.Format("{0} type must be blittable", (object) type));
      Profiler.Internal_EmitGlobalMetaData_Array((void*) &id, 16, tag, NoAllocHelpers.ExtractArrayFromList((object) data), data.Count, UnsafeUtility.SizeOf(type), true);
    }

    [Conditional("ENABLE_PROFILER")]
    public static unsafe void EmitFrameMetaData<T>(Guid id, int tag, NativeArray<T> data) where T : struct
    {
      Profiler.Internal_EmitGlobalMetaData_Native((void*) &id, 16, tag, (IntPtr) data.GetUnsafeReadOnlyPtr<T>(), data.Length, UnsafeUtility.SizeOf<T>(), true);
    }

    /// <summary>
    ///   <para>Write metadata associated with the whole Profiler session capture.</para>
    /// </summary>
    /// <param name="id">Unique identifier associated with the data.</param>
    /// <param name="tag">Data stream index.</param>
    /// <param name="data">Binary data.</param>
    [Conditional("ENABLE_PROFILER")]
    public static unsafe void EmitSessionMetaData(Guid id, int tag, Array data)
    {
      System.Type type = data != null ? data.GetType().GetElementType() : throw new ArgumentNullException(nameof (data));
      if (!UnsafeUtility.IsBlittable(type))
        throw new ArgumentException(string.Format("{0} type must be blittable", (object) type));
      Profiler.Internal_EmitGlobalMetaData_Array((void*) &id, 16, tag, data, data.Length, UnsafeUtility.SizeOf(type), false);
    }

    [Conditional("ENABLE_PROFILER")]
    public static unsafe void EmitSessionMetaData<T>(Guid id, int tag, List<T> data) where T : struct
    {
      if (data == null)
        throw new ArgumentNullException(nameof (data));
      System.Type type = typeof (T);
      if (!UnsafeUtility.IsBlittable(typeof (T)))
        throw new ArgumentException(string.Format("{0} type must be blittable", (object) type));
      Profiler.Internal_EmitGlobalMetaData_Array((void*) &id, 16, tag, NoAllocHelpers.ExtractArrayFromList((object) data), data.Count, UnsafeUtility.SizeOf(type), false);
    }

    [Conditional("ENABLE_PROFILER")]
    public static unsafe void EmitSessionMetaData<T>(Guid id, int tag, NativeArray<T> data) where T : struct
    {
      Profiler.Internal_EmitGlobalMetaData_Native((void*) &id, 16, tag, (IntPtr) data.GetUnsafeReadOnlyPtr<T>(), data.Length, UnsafeUtility.SizeOf<T>(), false);
    }

    [NativeMethod(Name = "ProfilerBindings::Internal_EmitGlobalMetaData_Array", IsFreeFunction = true, IsThreadSafe = true)]
    [NativeConditional("ENABLE_PROFILER")]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private static extern unsafe void Internal_EmitGlobalMetaData_Array(
      void* id,
      int idLen,
      int tag,
      Array data,
      int count,
      int elementSize,
      bool frameData);

    [NativeMethod(Name = "ProfilerBindings::Internal_EmitGlobalMetaData_Native", IsFreeFunction = true, IsThreadSafe = true)]
    [NativeConditional("ENABLE_PROFILER")]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private static extern unsafe void Internal_EmitGlobalMetaData_Native(
      void* id,
      int idLen,
      int tag,
      IntPtr data,
      int count,
      int elementSize,
      bool frameData);

    /// <summary>
    ///   <para>Enable or disable a given ProfilerCategory.</para>
    /// </summary>
    /// <param name="category">The category you want to enable or disable.</param>
    /// <param name="enabled">Enable or disable the collection of data for this category.</param>
    [Conditional("ENABLE_PROFILER")]
    public static void SetCategoryEnabled(ProfilerCategory category, bool enabled)
    {
      if ((int) (ushort) category == (int) (ushort) ProfilerCategory.Any)
        throw new ArgumentException("Argument should be a valid category", nameof (category));
      Profiler.Internal_SetCategoryEnabled((ushort) category, enabled);
    }

    /// <summary>
    ///   <para>Returns whether or not a given ProfilerCategory is currently enabled.</para>
    /// </summary>
    /// <param name="category">Which category you want to check the state of.</param>
    /// <returns>
    ///   <para>Returns whether or not a given ProfilerCategory is currently enabled.</para>
    /// </returns>
    public static bool IsCategoryEnabled(ProfilerCategory category)
    {
      return (int) (ushort) category != (int) (ushort) ProfilerCategory.Any ? Profiler.Internal_IsCategoryEnabled((ushort) category) : throw new ArgumentException("Argument should be a valid category", nameof (category));
    }

    /// <summary>
    ///   <para>Returns number of ProfilerCategory registered in Profiler.</para>
    /// </summary>
    /// <returns>
    ///   <para>Returns number of ProfilerCategory registered in Profiler.</para>
    /// </returns>
    [NativeHeader("Runtime/Profiler/ProfilerManager.h")]
    [StaticAccessor("profiling::GetProfilerManagerPtr()", StaticAccessorType.Arrow)]
    [NativeMethod(Name = "GetCategoriesCount")]
    [NativeConditional("ENABLE_PROFILER")]
    [MethodImpl(MethodImplOptions.InternalCall)]
    public static extern uint GetCategoriesCount();

    /// <summary>
    ///   <para>Returns all ProfilerCategory registered in Profiler.</para>
    /// </summary>
    /// <param name="categories"></param>
    [Conditional("ENABLE_PROFILER")]
    public static void GetAllCategories(ProfilerCategory[] categories)
    {
      for (int category = 0; (long) category < Math.Min((long) Profiler.GetCategoriesCount(), (long) categories.Length); ++category)
        categories[category] = new ProfilerCategory((ushort) category);
    }

    [Conditional("ENABLE_PROFILER")]
    public static void GetAllCategories(NativeArray<ProfilerCategory> categories)
    {
      for (int index = 0; (long) index < Math.Min((long) Profiler.GetCategoriesCount(), (long) categories.Length); ++index)
        categories[index] = new ProfilerCategory((ushort) index);
    }

    [NativeConditional("ENABLE_PROFILER")]
    [NativeMethod(Name = "profiler_set_category_enable", IsFreeFunction = true, IsThreadSafe = true)]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private static extern void Internal_SetCategoryEnabled(ushort categoryId, bool enabled);

    [NativeMethod(Name = "profiler_is_category_enabled", IsFreeFunction = true, IsThreadSafe = true)]
    [NativeConditional("ENABLE_PROFILER")]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private static extern bool Internal_IsCategoryEnabled(ushort categoryId);
  }
}
